'use strict'

const { ipcRenderer, ipcMain } = require('electron')
const ShareMenu = require('./share_menu')
const MentionMenu = require('./mention_menu')
const BadgeCount = require('./badge_count')
// const EmojiParser = require('./emoji_parser')
// const emojione = require('emojione')

const AppConfig = require('../../configuration')
const Common = AppConfig.readSettings('language') === 'zh_CN' ? require('../../common_cn') : require('../../common')

class Injector {
  init() {
    ipcRenderer.send("log", 'preload init')
    if (Common.DEBUG_MODE) {
      ipcRenderer.send("log", 'preload debug')
      Injector.lock(window, 'console', window.console)
    }
    this.initInjectBundle()
    this.initAngularInjection()
    this.lastUser = null
    this.initIPC()
  }

  initAngularInjection() {
    ipcRenderer.send('log', 'init angular injection')
    const self = this
    const angular = window.angular = {}
    let angularBootstrapReal
    Object.defineProperty(angular, 'bootstrap', {
      get: () => angularBootstrapReal ? function (element, moduleNames) {
        const moduleName = 'webwxApp'
        if (moduleNames.indexOf(moduleName) < 0) return
        let constants = null
        angular.injector(['ng', 'Services']).invoke(['confFactory', (confFactory) => {
          constants = confFactory
        }])
        angular.module(moduleName).config(['$httpProvider', ($httpProvider) => {
          $httpProvider.defaults.transformResponse.push((value) => {
            return self.transformResponse(value, constants)
          })
        },
        ]).run(['$rootScope', ($rootScope) => {
          ipcRenderer.send('wx-rendered', MMCgi.isLogin)

          $rootScope.$on('newLoginPage', () => {
            ipcRenderer.send('user-logged', '')
          })
          $rootScope.shareMenu = ShareMenu.inject
          $rootScope.mentionMenu = MentionMenu.inject
        }])
        return angularBootstrapReal.apply(angular, arguments)
      } : angularBootstrapReal,
      set: (real) => (angularBootstrapReal = real),
    })
  }

  initInjectBundle() {
    ipcRenderer.send('log', 'init inject bundle')

    const initModules = () => {
      if (!window.$) {
        return setTimeout(initModules, 500)
      }
      ipcRenderer.send("log", "wait window. end")
      MentionMenu.init()
      BadgeCount.init()
    }

    window.onload = () => {
      initModules()
      ipcRenderer.send("log", `navigator.onLine: ${navigator.onLine}`)
      window.addEventListener('online', () => {
        ipcRenderer.send('reload', true)
      })
    }
    ipcRenderer.send('log', 'init inject bundle end')
  }

  transformResponse(value, constants) {
    if (!value) return value

    switch (typeof value) {
      case 'object':
        /* Inject emoji stickers and prevent recalling. */
        return this.checkEmojiContent(value, constants)
      case 'string':
        /* Inject share sites to menu. */
        return this.checkTemplateContent(value)
    }
    return value
  }

  static lock(object, key, value) {
    return Object.defineProperty(object, key, {
      get: () => value,
      set: () => {},
    })
  }

  checkEmojiContent(value, constants) {
    if (!(value.AddMsgList instanceof Array)) return value
    value.AddMsgList.forEach((msg) => {
      switch (msg.MsgType) {
        // case constants.MSGTYPE_TEXT:
        //   msg.Content = EmojiParser.emojiToImage(msg.Content)
        //   break
        case constants.MSGTYPE_EMOTICON:
          Injector.lock(msg, 'MMDigest', '[Emoticon]')
          Injector.lock(msg, 'MsgType', constants.MSGTYPE_EMOTICON)
          if (msg.ImgHeight >= Common.EMOJI_MAXIUM_SIZE) {
            Injector.lock(msg, 'MMImgStyle', { height: `${Common.EMOJI_MAXIUM_SIZE}px`, width: 'initial' })
          } else if (msg.ImgWidth >= Common.EMOJI_MAXIUM_SIZE) {
            Injector.lock(msg, 'MMImgStyle', { width: `${Common.EMOJI_MAXIUM_SIZE}px`, height: 'initial' })
          }
          break
        case constants.MSGTYPE_RECALLED:
          if (AppConfig.readSettings('prevent-recall')) {
            Injector.lock(msg, 'MsgType', constants.MSGTYPE_SYS)
            Injector.lock(msg, 'MMActualContent', Common.MESSAGE_PREVENT_RECALL)
            Injector.lock(msg, 'MMDigest', Common.MESSAGE_PREVENT_RECALL)
          }
          break
      }
    })
    return value
  }

  checkTemplateContent(value) {
    // 修改页面
    const optionMenuReg = /optionMenu\(\);/
    const messageBoxKeydownReg = /editAreaKeydown\(\$event\)/
    if (optionMenuReg.test(value)) {
      value = value.replace(optionMenuReg, 'optionMenu();shareMenu();')
    } else if (messageBoxKeydownReg.test(value)) {
      value = value.replace(messageBoxKeydownReg, 'editAreaKeydown($event);mentionMenu($event);')
    }
    return value
  }

  initIPC() {
    ipcRenderer.send('log', 'init ipcRenderer Event')
    // clear currentUser to receive reddot of new messages from the current chat user
    ipcRenderer.on('hide-wechat-window', () => {
      ipcRenderer.send('log', 'ipcRenderer hide-wechat-window Event')
      this.lastUser = angular.element('#chatArea').scope().currentUser
      angular.element('.chat_list').scope().itemClick("")
    })
    // recover to the last chat user
    ipcRenderer.on('show-wechat-window', () => {
      ipcRenderer.send('log', 'ipcRenderer show-wechat-window Event')
      if (this.lastUser != null) {
        angular.element('.chat_list').scope().itemClick(this.lastUser)
      }
    })
    ipcRenderer.on('search', () => {
      $('#search_bar input')[0].focus()
    })
  }
}

new Injector().init()
